package com.sloth.controller;

import com.alibaba.fastjson.JSON;
import com.sloth.pojo.Customer;
import com.sloth.pojo.Myorder;
import com.sloth.service.MyOrderService;
import com.sloth.service.impl.MsgSender;
import com.sloth.util.RabbitMQConfiguration;
import com.sloth.util.ServerResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

/**
 * @author lai
 * @time 2021/10/12 20:04
 */
@Controller
public class MyOrderController {

    private static final Logger logger =  LoggerFactory.getLogger(MyOrderController.class);
    @Autowired
    private AmqpTemplate rabbitTemplate;

    @Autowired
    private MyOrderService myOrderService;

    @Autowired
    private MsgSender msgSender;


    // 使用 jsp 生成我的订单、订单详情，返回订单id，用于调用支付宝支付时传递订单id
    @PostMapping("order")
    @ResponseBody
    public Integer save(Customer customer, Integer selectAddressId, Double totalPrice, @RequestParam Map<String, String> selectProIds) {

        // 新加入的，订单id，因为订单编号是根据时间生成的，同一时间可能有多个用户下单，一个用户在某一时刻只能下一个订单，所以根据订单编号和用户id查找订单
        Integer myOrderId = 0;

        // 已经登录的用户id
        Integer customerId = customer.getCustId();


        // 遍历从前台接收到的数据，里面包含订单的总价格、收货地址id、订单中的商品id及其对应的商品数量
        Iterator<Map.Entry<String, String>> iterator = selectProIds.entrySet().iterator();

        // 新创建一个 Map 集合，用于接收从前端接收到的map中的商品id及其对应的数量信息
        HashMap<Integer, Integer> proIdCount = new HashMap<>();
        int len = selectProIds.size();
        for (int i = 0; i < len; i++) {
            while (iterator.hasNext()) {
                Map.Entry<String, String> next = iterator.next();
                String key = next.getKey();
                String value = next.getValue();
                if (key.startsWith("selectProIds")) {
                    String kkey = key.substring(key.indexOf("[") + 1, key.indexOf("]"));  // 将前端发送过来的有用数据 商品id 截取出来，赋给 map 的 key
                    proIdCount.put(Integer.parseInt(kkey), Integer.parseInt(value)); // 将得到的 商品id 和 与之对应的 商品的数量 放入map集合中
                }
            }
        }

        // 创建一个订单对象，用于调用 service 层，向后端发送数据
        Myorder myorder = new Myorder();
        Long time = new Date().getTime();
        // 因为会涉及到高并发，一个时刻可能有多个用户同时下单、生成订单，所以要连接用户id把订单编号设置为唯一的
        String orderNOString = customerId.toString() + time.toString();
        Long orderNO = Long.parseLong(orderNOString);
        myorder.setOrderNo(orderNO);  // 订单编号
        myorder.setCustId(customerId);  // 用户id
        myorder.setOrderDate(new Date());  // 订单创建时间
        myorder.setOrderPrice(totalPrice);  // 订单价格
        myorder.setAddressId(selectAddressId);  // 订单收货地址id
        myorder.setOrderStates(0);  // 订单状态，按照
        myorder.setState(0);  // 订单状态
        myOrderService.saveMyOrderAndOrderDetails(myorder, proIdCount); // 这个方法中直接将订单添加到数据库中，然后在通过

        // 所有有用的数据都已经得到了，向数据库中根据下单页面的商品的个数，生成对应数量的订单记录
        myOrderId = myOrderService.getMyOrderIdByMyOrderNoAndCustomerId(orderNO, customerId);

        // 通过 订单id 查询 订单
        Myorder myorder1 = myOrderService.getMyOrderByMyOrderID(myOrderId);

        // 生成订单之后，同时调用 MyOrderService 生成相应的订单详情信息
        // 在此直接将订单id传进 RabbitMQ 消息队列中进行排队，生成对应的有效时间，进行相应的处理

        // 有效时长
        /*Long effectiveTime = 60L;
        msgSender.addMyOrderMsg(myOrderId,effectiveTime);*/
        String myOrderString = JSON.toJSONString(myorder1);
        System.out.println("已经生成订单");

        this.rabbitTemplate.convertAndSend(
                RabbitMQConfiguration.orderExchange,  //发送至订单交换机
                RabbitMQConfiguration.routingKeyOrder, // 订单顶 routingKey
                myOrderString,
                message -> {
                    // 如果配置了 params.put("x-message-ttl",5 * 1000);
                    // 那么这一句话就可以省略，具体根据业务需要生命 QUEUE 的时候就制定好延迟时间，
                    // 队列中的延迟时间为 45 分钟，因为收银台页面的时间为 30 分钟，到支付还有 10 分钟，如果存在其他原因，会导致订单状态的修改
                    message.getMessageProperties().setExpiration( 1000 * 60 * 45 + "" );
                    System.out.println("在队列中添加订单信息");
                    System.out.println(new Date());
                    return message;
                }
        );

        return myOrderId;

    }


    @PostMapping("/demo")
    public void demo1(@RequestBody Map<Integer, Integer> map) {
        System.out.println(map.get(1));
    }


    // 巴 我的订单页面
    @GetMapping(value = {"/myorder/{odstate}", "/myorder"})
    @ResponseBody
    public ModelAndView getByCustomerIdAndOrder(@PathVariable(value = "odstate", required = false) Integer odstate, Customer customer) {

        ServerResponse serverResponse=null;
        if (customer==null){
//            return null;
        }else {
            serverResponse = myOrderService.getByCustomerIdAndOrder(customer.getCustId(), odstate);
        }

        ModelAndView mav = new ModelAndView();
        mav.addObject("serverResponse", serverResponse);
        //        System.out.println(serverResponse);
        mav.setViewName("order/myorder");
        return mav;
    }

    //通过修改订单详情的状态 实现删除订单
    @PostMapping("myorder/delete")
    public String update(Integer myOrderId) {

        myOrderService.update(myOrderId);
        return "redirect:/myorder";


    }
    //通过修改状态  进行去确认收货操作
    @PostMapping("myorder/dicision")
    public String updatedicision(Integer odDetailsId) {

        myOrderService.updatedicision(odDetailsId);


        return "redirect:/myorder";


    }


}
